package store.lunangangster.nodeflow.enums;

import store.lunangangster.nodeflow.common.BaseConstant;
import store.lunangangster.nodeflow.core.component.ExitComponent;
import store.lunangangster.nodeflow.core.component.IfComponent;
import store.lunangangster.nodeflow.core.component.ForComponent;
import store.lunangangster.nodeflow.core.component.NodeComponent;
import java.util.regex.Pattern;
import store.lunangangster.nodeflow.core.component.SwitchComponent;
import store.lunangangster.nodeflow.core.component.WhileComponent;

/**
 * Node类型枚举类
 *
 * @author cwk
 * @version 1.0
 */
public enum NodeType {

	NODE_COMMON(BaseConstant.COMMON, NodeComponent.class, Pattern.compile("^\\w+$")),
	NODE_IF(BaseConstant.IF, IfComponent.class, Pattern.compile("^\\w+\\s*\\(\\s*\\w+\\s*(\\|\\s*\\w+\\s*)?\\)$")),
	NODE_FOR(BaseConstant.FOR, ForComponent.class, Pattern.compile("^for\\s*\\(\\s*\\w+\\s*;\\s*\\w+\\s*\\)$")),
	NODE_WHILE(BaseConstant.WHILE, WhileComponent.class, Pattern.compile("^while\\s*\\(\\s*\\w+\\s*\\)\\s*\\{[\\w\\s;]*\\}$")),
	NODE_EXIT(BaseConstant.EXIT, ExitComponent.class, null),
	NODE_SWITCH(BaseConstant.SWITCH, SwitchComponent.class, Pattern.compile("^switch\\s*\\(\\w+\\)\\s*\\{[\\w\\s|]*}$"));

	private final String name;
	private final Class<? extends NodeComponent> clazz;
	public final Pattern valuePattern;

	NodeType(String name, Class<? extends NodeComponent> clazz, Pattern valuePattern) {
		this.name = name;
		this.clazz = clazz;
		this.valuePattern = valuePattern;
	}

	/**
	 * 根据子类Class推测Node类型：如A extend NodeComponent，则可根据A.class获取到getNodeType(NodeComponent.class)
	 * @param clazz 如果是NodeComponent以及其子类的对象，则会获取其相应的NodeType对象；否则返回null
	 * @return 返回NodeComponent子类对应的NodeType；如果是非法的clazz则返回null
	 */
	public static NodeType guessType(Class<?> clazz) {
		if (clazz == null) {
			return null;
		}
		while (true) {
			Class<?> superclass = clazz.getSuperclass();
			if (Object.class.equals(superclass)) {
				return null;
			}
			String packageName = superclass.getPackage().getName();
			// 如果父类是component包下的组件，则返回组件类型
			if (packageName.startsWith(BaseConstant.COMP_PACKAGE)) {
				return NodeType.getNodeType(superclass);
			}
		}
	}

	private static NodeType getNodeType(Class<?> clazz) {
		if (clazz == null) {
			return null;
		}
		for (NodeType type : values()) {
			if (type.getClazz().equals(clazz)) {
				return type;
			}
		}
		return null;
	}

	/**
	 * 获取NodeType的name字段
	 * @return	NodeType对应的String name
	 */
	public String getName() {
		return name;
	}

	/**
	 * 获取NodeType对应的NodeComponent以及其子类的Class对象
	 * @return	clazz extends NodeComponent
	 */
	public Class<? extends NodeComponent> getClazz() {
		return clazz;
	}
}
